//; ---------------------------------------------------------------------------
//; Object 34 - zone title cards
//; ---------------------------------------------------------------------------

#include "titlecard.h"

#include "../sprite.h"
#include "../objectsystemNEWER.h"
#include "../plcsystem.h"

#define SWAPWORD(val) (((val&0x00FF)<<8)+((val&0xFF00)>>8))

static object *obj;

//EXTERN DEFINITIONS HERE
extern byte v_zone;
extern byte v_act;

//; ---------------------------------------------------------------------------
//; Sprite mappings - zone title cards
//; ---------------------------------------------------------------------------
byte M_Card_GHZ[46] = { 9, 			     //; GREEN HILL
		 0xF8, 5, 0,	0x18, 0xB4,
		 0xF8, 5, 0,	0x3A, 0xC4,
		 0xF8, 5, 0,	0x10, 0xD4,
		 0xF8, 5, 0,	0x10, 0xE4,
		 0xF8, 5, 0,	0x2E, 0xF4,
		 0xF8, 5, 0,	0x1C, 0x14,
		 0xF8, 1, 0,	0x20, 0x24,
		 0xF8, 5, 0,	0x26, 0x2C,
		 0xF8, 5, 0,	0x26, 0x3C
};

byte M_Card_LZ[46] = {	 9,			      //; LABYRINTH
		 0xF8, 5, 0,	0x26, 0xBC,
		 0xF8, 5, 0,	   0, 0xCC,
		 0xF8, 5, 0,	   4, 0xDC,
		 0xF8, 5, 0,	0x4A, 0xEC,
		 0xF8, 5, 0,	0x3A, 0xFC,
		 0xF8, 1, 0,	0x20,  0xC,
		 0xF8, 5, 0,	0x2E, 0x14,
		 0xF8, 5, 0,	0x42, 0x24,
		 0xF8, 5, 0,	0x1C, 0x34
};

byte M_Card_MZ[31] = {	 6,			     //; MARBLE
		 0xF8, 5, 0,	0x2A, 0xCF,
		 0xF8, 5, 0,	   0, 0xE0,
		 0xF8, 5, 0,	0x3A, 0xF0,
		 0xF8, 5, 0,	   4,    0,
		 0xF8, 5, 0,	0x26, 0x10,
		 0xF8, 5, 0,	0x10, 0x20
};

byte M_Card_SLZ[46] = {  9,			    //; STAR LIGHT
		 0xF8, 5, 0,	0x3E, 0xB4,
		 0xF8, 5, 0,	0x42, 0xC4,
		 0xF8, 5, 0,	   0, 0xD4,
		 0xF8, 5, 0,	0x3A, 0xE4,
		 0xF8, 5, 0,	0x26,    4,
		 0xF8, 1, 0,	0x20, 0x14,
		 0xF8, 5, 0,	0x18, 0x1C,
		 0xF8, 5, 0,	0x1C, 0x2C,
		 0xF8, 5, 0,	0x42, 0x3C
};
byte M_Card_SYZ[51] = {  0xA,			    //; SPRING YARD
		 0xF8, 5, 0,	0x3E, 0xAC,
		 0xF8, 5, 0,	0x36, 0xBC,
		 0xF8, 5, 0,	0x3A, 0xCC,
		 0xF8, 1, 0,	0x20, 0xDC,
		 0xF8, 5, 0,	0x2E, 0xE4,
		 0xF8, 5, 0,	0x18, 0xF4,
		 0xF8, 5, 0,	0x4A, 0x14,
		 0xF8, 5, 0,	   0, 0x24,
		 0xF8, 5, 0,	0x3A, 0x34,
		 0xF8, 5, 0,	 0xC, 0x44
};
byte M_Card_SBZ[51] = {  0xA,			    //SCRAP BRAIN
		 0xF8, 5, 0,	0x3E, 0xAC,
		 0xF8, 5, 0,	   8, 0xBC,
		 0xF8, 5, 0,	0x3A, 0xCC,
		 0xF8, 5, 0,	   0, 0xDC,
		 0xF8, 5, 0,	0x36, 0xEC,
		 0xF8, 5, 0,	   4,  0xC,
		 0xF8, 5, 0,	0x3A, 0x1C,
		 0xF8, 5, 0,	   0, 0x2C,
		 0xF8, 1, 0,	0x20, 0x3C,
		 0xF8, 5, 0,	0x2E, 0x44
};

byte M_Card_Zone[21] = {   4,			
		 0xF8, 5, 0,	0x4E, 0xE0,
		 0xF8, 5, 0,	0x32, 0xF0,
		 0xF8, 5, 0,	0x2E,    0,
		 0xF8, 5, 0,	0x10, 0x10
};

byte M_Card_Act1[11] = {   2,			    //; ACT 1
		    4,	0xC, 0, 0x53, 0xEC,
		 0xF4,    2, 0,	0x57,  0xC
};

byte M_Card_Act2[11] = {   2,			    //; ACT 2
		    4,	0xC, 0, 0x53, 0xEC,
		 0xF4,    6, 0,	0x5A,    8
};

byte M_Card_Act3[11] = {   2,			     //; ACT 3
		    4,	0xC, 0, 0x53, 0xEC,
		 0xF4,    6, 0,	0x60,    8
};
byte M_Card_Oval[71] = { 0xD,			        //; Oval
		 0xE4, 0xC,    0,  0x70, 0xF4,
		 0xE4,   2,    0,  0x74, 0x14,
		 0xEC,   4,    0,  0x77, 0xEC,
		 0xF4,   5,    0,  0x79, 0xE4,
		 0x14, 0xC, 0x18,  0x70, 0xEC,
		    4,	 2, 0x18,  0x74, 0xE4,
		  0xC,   4, 0x18,  0x77,    4,
		 0xFC,   5, 0x18,  0x79,  0xC,
		 0xEC,   8,    0,  0x7D, 0xFC,
		 0xF4, 0xC,    0,  0x7C, 0xF4,
		 0xFC,   8,    0,  0x7C, 0xF4,
		    4, 0xC,    0,  0x7C, 0xEC,
		  0xC,   8,    0,  0x7C, 0xEC
};

byte M_Card_FZ[26] = {	 5,			        //; FINAL
		 0xF8, 5, 0,	0x14, 0xDC,
		 0xF8, 1, 0,	0x20, 0xEC,
		 0xF8, 5, 0,	0x2E, 0xF4,
		 0xF8, 5, 0,	   0,    4,
		 0xF8, 5, 0,	0x26, 0x14
};

byte *Map_Card[12] = { M_Card_GHZ,    M_Card_LZ,   M_Card_MZ,  M_Card_SLZ, M_Card_SYZ,  M_Card_SBZ, 
                     M_Card_Zone, M_Card_Act1, M_Card_Act2, M_Card_Act3, M_Card_Oval,  M_Card_FZ  };


//==========

#define card_mainX 0x30		//; position for card to display on
#define card_finalX 0x32        //; position for card to finish on
void (*Card_Index[4])() = { Card_CheckSBZ3, Card_ChkPos, Card_Wait, Card_Wait };


                  //; y-axis position, A, B   A=routine number, B=frame number (changes)
byte Card_ItemData[16] = { 0x00, 0xD0, 2, 0,
                           0x00, 0xE4, 2, 6,
                           0x00, 0xEA, 2, 7, 
                           0x00, 0xE0, 2, 10 };

//; ---------------------------------------------------------------------------
//; Title	card configuration data
//; Format:
//; 4 bytes per item (YYYY XXXX)      (start offscreen at YYYY, scroll to XXXX, wait, scroll back to YYYY)
//; 4 items per level (GREEN HILL, ZONE, ACT X, oval)
//; ---------------------------------------------------------------------------
word Card_ConData[56] = { 0,	0x120, 0xFEFC, 0x13C, 0x414, 0x154, 0x214, 0x154,   //; GHZ
		          0,	0x120, 0xFEF4, 0x134, 0x40C, 0x14C, 0x20C, 0x14C,   //; LZ
		          0,	0x120, 0xFEE0, 0x120, 0x3F8, 0x138, 0x1F8, 0x138,   //; MZ
		          0,	0x120, 0xFEFC, 0x13C, 0x414, 0x154, 0x214, 0x154,   //; SLZ
		          0,	0x120, 0xFF04, 0x144, 0x41C, 0x15C, 0x21C, 0x15C,   //; SYZ
		          0,	0x120, 0xFF04, 0x144, 0x41C, 0x15C, 0x21C, 0x15C,   //; SBZ
		          0,	0x120, 0xFEE4, 0x124, 0x3EC, 0x3EC, 0x1EC, 0x12C    //; FZ
};

//OBJECT:					; XREF: Obj_Index
void TitleCard(object *_obj)
{
    obj = _obj;

    //moveq	#0,d0
    //move.b	obRoutine(a0),d0
    byte routine = obj->Routine/2;

    //move.w	Card_Index(pc,d0.w),d1
    //jmp	Card_Index(pc,d1.w)
    (*Card_Index[routine])();
}

//; ===========================================================================

//Card_CheckSBZ3:	; Routine 0
void Card_CheckSBZ3()
{
    //Card_CheckSBZ3:	; Routine 0
    //movea.l	a0,a1
    object *cardPiece = obj;

    //moveq	#0,d0
    //move.b	(v_zone).w,d0
    byte cardNum = v_zone;	

    //cmpi.w	#(id_LZ<<8)+3,(v_zone).w ; check if level is SBZ 3
    //bne.s	Card_CheckFZ
    //moveq	#5,d0		; load title card number 5 (SBZ)
    /*if (v_zone == (id_LZ<<8)+3);
        cardNum = 5;
    */

    //Card_CheckFZ:
    //move.w	d0,d2
    word cardMap = cardNum;	
  	
    //cmpi.w	#(id_SBZ<<8)+2,(v_zone).w ; check if level is FZ
    /* if (v_zone == (id_SBZ<<8)+2)
    {	
	//bne.s	Card_LoadConfig
	//moveq	#6,d0		; load title card number 6 (FZ)
        cardNum = 6;
		
        //moveq	#$B,d2		; use "FINAL" mappings
        cardMap = 0xB;
    } */

    //Card_LoadConfig:
    //lea	(Card_ConData).l,a3
    //lsl.w	#4,d0
    //adda.w	d0,a3
    word *cardConfig = Card_ConData + (cardNum * 8);

    //lea	(Card_ItemData).l,a2
    word *cardItem = (word*)Card_ItemData;

    //moveq	#3,d1
    for (long loopCount = 3; loopCount >= 0; loopCount--)
    {
        //Card_Loop:
        //move.b	#id_TitleCard,0(a1)
        cardPiece->ID = id_TitleCard;
   
        //move.w	(a3),obX(a1)	; load start x-position
        cardPiece->X = *(cardConfig);                                     //0

        signed short finalX = *(cardConfig++);
        //move.w	(a3)+,card_finalX(a1) ; load finish x-position (same as start)
        ptrsetobjvariableword(card_finalX, cardPiece, finalX);

        signed short mainX = *(cardConfig++);
        //move.w	(a3)+,card_mainX(a1) ; load main x-position
        ptrsetobjvariableword(card_mainX, cardPiece, mainX);              //0x120            //0-0x120-0

        word cardY = *(cardItem++);
        //move.w	(a2)+,obScreenY(a1)
        cardPiece->ScreenY = SWAPWORD(cardY);                           //each of the 4 have their own y...

        byte *cardBytes = (byte*)cardItem;                            //
        //move.b	(a2)+,obRoutine(a1)
        //move.b	(a2)+,d0
        cardPiece->Routine = *(cardBytes++);                          //always 2
        byte cardFrame = *(cardBytes++);                              //determines which of the texts to display (Green Hill, Zone, Act, etc.)
        cardItem++; 

        //bne.s	Card_ActNumber
        if (cardFrame == 0) {
            //move.b	d2,d0
            cardFrame = cardMap;
        }

        //Card_ActNumber:
        //cmpi.b	#7,d0
        //bne.s	Card_MakeSprite
        if (cardFrame == 7)
        {	
            //add.b	(v_act).w,d0
	    cardFrame = cardFrame + v_act;	

            //cmpi.b	#3,(v_act).w
	    //bne.s	Card_MakeSprite
	    //subq.b	#1,d0
            if (v_act == 3) { cardFrame = cardFrame - 1; }
        }

        //Card_MakeSprite:
        //move.b	d0,obFrame(a1)	; display frame	number d0
        cardPiece->Frame = cardFrame; 

        //move.l	#Map_Card,obMap(a1)
        cardPiece->Map = Map_Card;

        //move.w	#$8580,obGfx(a1)
        cardPiece->Gfx = 0x8580;

        //move.b	#$78,obActWid(a1)
        cardPiece->ActionWidth = 0x78;

        //move.b	#0,obRender(a1)
        cardPiece->Render = 0;
 
        //move.b	#0,obPriority(a1)
        cardPiece->Priority = 0;

        //move.w	#60,obTimeFrame(a1) ; set time delay to 1 second
        cardPiece->TimeFrame = 60;

        //lea	$40(a1),a1	; next object
        cardPiece = cardPiece + 1;

        //dbf	d1,Card_Loop	; repeat sequence another 3 times
    }
}


//; ===========================================================================



//Card_ChkPos:	; Routine 2
void Card_ChkPos()
{
    //moveq	#$10,d1		; set horizontal speed
    long cardHSpeed = 0x10;

    //move.w	card_mainX(a0),d0
    signed short cardX = ptrgetobjvariableword(card_mainX, obj);

    //cmp.w	obX(a0),d0	; has item reached the target position?
    //beq.s	Card_NoMove	; if yes, branch
    if (cardX != (signed short)obj->X)
    {	
        //bge.s	Card_Move
        if (cardX < (signed short)obj->X)
        {
	    //neg.w	d1
            cardHSpeed = -cardHSpeed;
        }
       
        //Card_Move:
	//add.w	d1,obX(a0)	; change item's position
        obj->X = obj->X + cardHSpeed;
    }

    //Card_NoMove:
    //move.w	obX(a0),d0
    cardX = obj->X;

    //bmi.s	locret_C3D8
    //cmpi.w	#$200,d0	; has item moved beyond	$200 on	x-axis?
    //bcc.s	locret_C3D8	; if yes, branch
    if (cardX >= 0 && cardX <= 0x200)
    {
        //bra.w	DisplaySprite
        DisplaySprite(obj);
    }

    //locret_C3D8:
    //rts	
}   //; ===========================================================================

//; ===========================================================================

//Card_Wait:	; Routine 4/6
void Card_Wait()
{
    //tst.w	obTimeFrame(a0)	; is time remaining zero?
    //beq.s	Card_ChkPos2	; if yes, branch
    if (obj->TimeFrame != 0)
    {
        //subq.w	#1,obTimeFrame(a0) ; subtract 1 from time
        obj->TimeFrame = obj->TimeFrame - 1;

	//bra.w	DisplaySprite
        DisplaySprite(obj);
    }
    //; ===========================================================================
    else
    {
        //Card_ChkPos2:				; XREF: Card_Wait
	//tst.b	obRender(a0)
        //bpl.s	Card_ChangeArt
        if ((signed char)obj->Render >= 0) { Card_ChangeArt(); }
        else 
        {
	    //moveq	#$20,d1
            signed short movex = 0x20;

	    //move.w	card_finalX(a0),d0
            signed short finalX = ptrgetobjvariableword(card_finalX, obj);

	    //cmp.w	obX(a0),d0	; has item reached the finish position?
            //beq.s	Card_ChangeArt	; if yes, branch
            if (finalX == obj->X) { Card_ChangeArt(); }
            else
            {
	        //bge.s	Card_Move2
		if (finalX < obj->X)
                {
                    //neg.w	d1
                    movex = -movex;
                }
            
                //Card_Move2:
		//add.w	d1,obX(a0)	; change item's position
		obj->X = obj->X + movex;

                //move.w	obX(a0),d0
                finalX = obj->X;

	        //bmi.s	locret_C412
                //cmpi.w	#$200,d0	; has item moved beyond	$200 on	x-axis?
		//bcc.s	locret_C412	; if yes, branch
                if (finalX >= 0 && finalX <= 0x200)
                {
		    //bra.w	DisplaySprite
                    DisplaySprite(obj);
                }
                //; ===========================================================================

                //locret_C412:
		//rts	
                //; ===========================================================================
            }
        }
    }
}

//Card_ChangeArt:			; XREF: Card_ChkPos2
void Card_ChangeArt()
{
    //cmpi.b	#4,obRoutine(a0)
    //bne.s	Card_Delete
    if (obj->Routine == 4)
    {
        #define plcid_Explode 2
        //moveq	#plcid_Explode,d0
        //jsr	(AddPLC).l	; load explosion gfx
        AddPLC(plcid_Explode);

        #define plcid_GHZAnimals 0x15
        //moveq	#0,d0
        //move.b	(v_zone).w,d0
        byte curZone = v_zone;
        //addi.w	#plcid_GHZAnimals,d0
        word anmlPLC = curZone + plcid_GHZAnimals;
        //jsr	(AddPLC).l	; load animal gfx (level no. + $15)
        AddPLC(anmlPLC); 
    }

    //Card_Delete:
    //bra.w	DeleteObject
    DeleteObject(obj);

}   //; ===========================================================================



